package face.pay.profit;

import com.google.common.cache.Cache;
import face.pay.cache.LocalCache;
import face.pay.constant.OemType;
import face.pay.constant.UserType;
import face.pay.dao.*;
import face.pay.entity.EnterpriseInfo;
import face.pay.entity.OemInfo;
import face.pay.entity.PayUserInfo;
import face.pay.entity.UserInfo;
import face.pay.profit.core.RelationInfo;
import face.pay.profit.core.RelationType;
import face.pay.util.MathUtil;
import face.pay.vo.ProfitUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;

/**
 * @Auther: zkj
 * @Date: 2019/8/5 10:42
 * @Description: 获取用户 分佣 层级关系以及分佣 信息
 */
@Component
@Slf4j
public class UserProfitBiz {

    /**
     *  默认策略 代理商 级别 前缀
     */
    private static final String AGENCY_USER_KEY_PREFIX = "AGENCY_LEVEL_USER_";

    /**
     *  百分比分佣策略下  代理商-推荐关系 3级 前缀
     */
    private static final String PERCENTAGE_USER_KEY_PREFIX = "AGENCY_PERCENTAGE_USER_";

    private static final String DEFAULY_USER_PREFIX = "DEFAULY_";

    private static final String PERCENTAGE_USER_PREFIX = "PERCENTAGE_";



    @Autowired
    EnterpriseInfoDao enterpriseInfoDao;

    @Autowired
    AgencyLevelDao agencyLevelDao;

    @Autowired
    ProfitInfoDao profitInfoDao;

    @Autowired
    UserInfoDao userInfoDao;

    @Autowired
    OemInfoDao oemInfoDao;

    @Autowired
    PayUserInfoDao payUserInfoDao;

    private Cache cache = LocalCache.cache;

    /**
     * 获取默认分润策略 商家-代理层级关系
     * @param userId
     * @return
     */
    public RelationInfo getUserRelation(Integer userId){

        log.info("获取商家-代理关系 userId "+userId);

        RelationInfo userRelationInfo = (RelationInfo)cache.getIfPresent(DEFAULY_USER_PREFIX+String.valueOf(userId));

        if(userRelationInfo==null){
            log.info("缓存失效 从数据库中获取 ");
            userRelationInfo = this.getDbUserRelation(userId);
        }
        
        return  userRelationInfo;
    }


    /**
     * 百分比模式下 代理商层级关系
     * @param userId
     * @return
     */
    public RelationInfo getParUserRelation(Integer userId){
        log.info("获取商家-代理关系 userId "+userId);

        RelationInfo userRelationInfo = (RelationInfo)cache.getIfPresent(PERCENTAGE_USER_PREFIX+String.valueOf(userId));

        if(userRelationInfo==null){
            log.info("缓存失效 从数据库中获取 ");
            userRelationInfo = this.getDbUserRecRelation(userId);
        }

        return  userRelationInfo;
    }



    private RelationInfo getDbUserRelation(Integer userId) {

        RelationInfo userRelationInfo =  new RelationInfo(userId);

        try{

            UserInfo userInfo =  this.userInfoDao.getById(userId);

            Integer oemId = userInfo.getOemId();

            OemInfo oemInfo  =  this.oemInfoDao.getOemInfoById(oemId);
            if(oemInfo==null){
                return  null;
            }else {
                userRelationInfo.setOemInfo(oemInfo);
            }

            if(UserType.ENTERPRISE.equals(userInfo.getType())){

                log.info("商家用户");
                Integer profitId = userInfo.getProfitId();

                /**
                 * 推荐人
                 */
                Integer parUserId = userInfo.getRecommendId();

                /**
                 * 所属代理商 （某种情况下 推荐人就是代理商）
                 */
                Integer agencyUserId = userInfo.getAgencyId();
                log.info("商家用户 分佣信息");
                ProfitUser mch_user = this.userInfoDao.getUserWithMchProfit(userId);

                userRelationInfo.put(RelationType.MCH_USER,mch_user);

                /**
                 * 代理商用户
                 */
                ProfitUser agency_user =  this.userInfoDao.getUserWithLevelProfit(agencyUserId);

                userRelationInfo.put(RelationType.AGENCY_USER,agency_user);
                log.info("开始搜索 商家所属代理商 分佣体系");
                checkAgencyUser(agency_user,userRelationInfo);

                log.info("开始搜索 OEM 商户信息");
                checkOemUser(oemId,userRelationInfo);

                log.info("分佣体系 搜索结束");
                cache.put(DEFAULY_USER_PREFIX+String.valueOf(userId),userRelationInfo);

                return  userRelationInfo;
            }


        }catch (Exception e){
            log.error("查询分佣体系异常",e);
        }
        return  null;
    }


    /**
     * 商家推荐 三级关系
     * @param userId
     * @return
     */
    private RelationInfo getDbUserRecRelation(Integer userId) {

        RelationInfo userRelationInfo =  new RelationInfo(userId);

        try{

            UserInfo userInfo =  this.userInfoDao.getById(userId);

            Integer oemId = userInfo.getOemId();

            OemInfo oemInfo  =  this.oemInfoDao.getOemInfoById(oemId);
            if(oemInfo==null){
                return  null;
            }else {
                userRelationInfo.setOemInfo(oemInfo);
            }
            if(UserType.ENTERPRISE.equals(userInfo.getType())){

                log.info("商家用户");
                Integer profitId = userInfo.getProfitId();

                /**
                 * 推荐人
                 */
                Integer parUserId = userInfo.getRecommendId();

                /**
                 * 所属代理商 （某种情况下 推荐人就是代理商）
                 */
                Integer agencyUserId = userInfo.getAgencyId();
                log.info("商家用户 分佣信息");
                ProfitUser mch_user = this.userInfoDao.getUserWithMchProfit(userId);

                userRelationInfo.put(RelationType.MCH_USER,mch_user);

                /**
                 * 代理商用户
                 */
                ProfitUser agency_user =  this.userInfoDao.getUserWithLevelProfit(agencyUserId);

                userRelationInfo.put(RelationType.AGENCY_USER,agency_user);


                log.info("开始搜索 商家所属代理商 分佣体系");
                checkParAgencyUser(agency_user,userRelationInfo);

                log.info("开始搜索 OEM 商户信息");
                checkOemUser(oemId,userRelationInfo);

                log.info("分佣体系 搜索结束");

                cache.put(PERCENTAGE_USER_KEY_PREFIX+String.valueOf(userId),userRelationInfo);

                return  userRelationInfo;
            }



        }catch (Exception e){
            log.error("查询分佣体系异常",e);
        }


        return  null;
    }


    private void checkAgencyUser(ProfitUser agencyUser, RelationInfo userRelationInfo){

        /**
         * 查找 agencyUser 父级 一直往上找到 代理商等级为1
         * 子级与父级 平级 则跳过
         */
        Integer level = agencyUser.getLevel();

        String key =AGENCY_USER_KEY_PREFIX+String.valueOf(level);

        /**
         * 检测 该等级用户分佣 信息是否已经放入缓存
         * 如果该等级已经有缓存
         * 则跳过
         */
        ProfitUser profitUser = userRelationInfo.get(key);
        if(profitUser==null){
            log.info("分佣 key"+key);
            userRelationInfo.put(key,agencyUser);
        }

        if(new Integer(1).equals(level)){
            log.info("检索发现 最高等级  结束搜索" );
            return;
        }else{

            Integer parId = agencyUser.getParId();

            ProfitUser parProfitUser = this.userInfoDao.getUserWithLevelProfit(parId);

            if(parProfitUser!=null){
                checkAgencyUser(parProfitUser,userRelationInfo);
            }

        }

    }

    /**
     * 商家
     * @param agencyUser
     * @param userRelationInfo
     */
    private void checkParAgencyUser(ProfitUser agencyUser, RelationInfo userRelationInfo){

        /**
         * 查找 agencyUser 父级 一直往上找 两级
         */
        Integer level = agencyUser.getLevel();

        String key =RelationType.AGENCY_PERCENTAGE_USER_INDIRECT;

        /**
         * 检测 该等级用户分佣 信息是否已经放入缓存
         * 如果该等级已经有缓存
         * 则跳过
         */
        Integer parId = agencyUser.getParId();

        ProfitUser indirectUser = this.userInfoDao.getUserWithLevelProfit(parId);

        if(indirectUser!=null && UserType.AGENCY.equals(indirectUser.getUserType())) {
            log.info("分佣 key " + key);
            userRelationInfo.put(key, indirectUser);
            parId = indirectUser.getParId();

            ProfitUser thirdUser = this.userInfoDao.getUserWithLevelProfit(parId);

            if (thirdUser != null && UserType.AGENCY.equals(thirdUser.getUserType())) {
                userRelationInfo.put(RelationType.AGENCY_PERCENTAGE_USER_THIRD, thirdUser);
            }

        }


    }

    private void checkOemUser(Integer oemId, RelationInfo userRelationInfo){
            ProfitUser oemProfitUser = this.userInfoDao.getOemUserByOemId(oemId);
            userRelationInfo.put(RelationType.OEM_USER,oemProfitUser);
    }


}
